package com.crowd.service.impl;

import com.crowd.constant.CrowdConstant;
import com.crowd.entity.Admin;
import com.crowd.entity.AdminExample;
import com.crowd.exception.LoginAccountAlreadyExistException;
import com.crowd.exception.LoginFailedException;
import com.crowd.mapper.AdminMapper;
import com.crowd.service.api.IAdminService;
import com.crowd.util.CrowdUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author Stone
 * @date 2020/4/27 15:56
 */
@Service
@Transactional
public class AdminServiceImpl implements IAdminService {
    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    /**
     * @Author:Stone
       * @Param admin:
       * @return: void
     * @Date: 2020/5/14 16:06
     * @Description:保存新用户信息，并且对密码进行md5加密
    */
    @Override
    public void saveAdmin(Admin admin) {
        // 生成当前系统时间
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String createTime = sdf.format(date);
        admin.setCreateTime(createTime);
        // 针对登录密码进行加密
        String password = admin.getUserPswd();
//        String encoded = CrowdUtil.md5(password);
        // 使用springSecurity盐值进行加密
        String encoded =bCryptPasswordEncoder.encode(password);
        admin.setUserPswd(encoded);
        // 执行保存，如果账户被占用会抛出异常
        try {
            adminMapper.insert(admin);
        }catch (Exception e){
            e.printStackTrace();
            // 检测当前捕获的异常对象，如果是DuplicateKeyException 类型说明是账号重复导致的
            if(e instanceof DuplicateKeyException){
                throw new LoginAccountAlreadyExistException(CrowdConstant.MESSAGE_LOGIN_ACCT_ALREADY_IN_USE);
            }
            throw e;
        }


    }

    /**
     * @Author:Stone

       * @return: java.util.List<com.crowd.entity.Admin>
     * @Date: 2020/5/16 14:06
     * @Description:找出所有admin数据
    */
    @Override
    public List<Admin> findAll() {
        return adminMapper.selectByExample(new AdminExample());
    }

    /**
     * @Author:Stone
       * @Param null:
       * @return: null
     * @Date: 2020/5/16 14:05
     * @Description:根据id找对象
    */
    @Override
    public Admin findByPrimaryKey(Integer id) {
        Admin admin = adminMapper.selectByPrimaryKey(id);
        return admin;
    }

    @Override
    public Admin getAdminByLoginAcct(String loginAcct, String userPswd) {
        // 1.根据登录账号查询Admin 对象
        // 1.1创建AdminExample 对象
        AdminExample adminExample = new AdminExample();
        // 1.2创建Criteria 对象
        AdminExample.Criteria criteria =  adminExample.createCriteria();
        // 1.3在Criteria 对象中封装查询条件
        criteria.andLoginAcctEqualTo(loginAcct);
        // 1.4调用AdminMapper 的方法执行查询
        List<Admin> adminList = adminMapper.selectByExample(adminExample);
        // 2.判断Admin 对象是否为null
        if(adminList == null || adminList.size() == 0){
            throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAIL);
        }
        if( adminList.size() > 1){
            throw new LoginFailedException(CrowdConstant.MESSAGE_SYSTEM_ERROR_LOGIN_NOT_UNIQUE);
        }
        // 3.如果Admin 对象为null 则抛出异常
        if(adminList.get(0) == null){
            throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAIL);
        }
        // 4.如果Admin 对象不为null 则将数据库密码从Admin 对象中取出
        Admin admin = adminList.get(0);
        String userPswdDB = admin.getUserPswd();
        // 5.将表单提交的明文密码进行加密
        String userPswdForm = CrowdUtil.md5(userPswd);
        // 6.对密码进行比较
        if(userPswdDB==null && !userPswdDB.equals(userPswdForm)){
            // 7.如果比较结果是不一致则抛出异常
            throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAIL);

        }else{
            // 8.如果一致则返回Admin 对象
            return admin;
        }


    }

    /**
     * @Author:Stone
       * @Param keyword:
     * @Param pageNum:
     * @Param pageSize:
       * @return: com.github.pagehelper.PageInfo<com.crowd.entity.Admin>
     * @Date: 2020/5/11 14:18
     * @Description:使用pageHelper对adminList进行分页
    */
    @Override
    public PageInfo<Admin> getAdminPage(String keyword,int pageNum,int pageSize) {
        // 1.开启分页功能
        PageHelper.startPage(pageNum, pageSize);
        // 2.查询Admin 数据
        List<Admin> adminList = adminMapper.selectAdminByKeyword(keyword);
        // 3.为了方便页面显示，将List封装成PageInfo对象返回
        PageInfo<Admin> pageInfo = new PageInfo<>(adminList);

        return pageInfo;
    }

    /**
     * @Author:Stone
       * @Param id:
       * @return: void
     * @Date: 2020/5/16 14:19
     * @Description:通过id删除用户
    */
    @Override
    public void remove(Integer id) {
        adminMapper.deleteByPrimaryKey(id);
    }

    /**
     * @Author:Stone
       * @Param admin:
       * @return: void
     * @Date: 2020/5/16 14:19
     * @Description:更新用户信息
    */
    @Override
    public void update(Admin admin) {
        adminMapper.updateByPrimaryKeySelective(admin);
    }

    /**
     * @Author:Stone
       * @Param loginAcct:
       * @return: com.crowd.entity.Admin
     * @Date: 2020/6/3 21:59
     * @Description: 根据loginAcct来找Admin
    */
    @Override
    public Admin getAdminByLoginAcct(String loginAcct) {
        AdminExample adminExample = new AdminExample();
        AdminExample.Criteria criteria = adminExample.createCriteria();
        criteria.andLoginAcctEqualTo(loginAcct);
        List<Admin> adminList = adminMapper.selectByExample(adminExample);
        Admin admin = adminList.get(0);
        return admin;
    }
}
